﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading;
using DBMan.Common.Global;
using DBMan.Common.Helper;
using DBMan.Common.Helper.SQLServer;

namespace DBMan
{
    /// <summary>
    /// 处理类
    /// </summary>
    public partial class Deal
    {
        public readonly static Deal Instance = new Deal();

        private const string LOG_ERR_FILE = "LogErr.txt";
        private const string LOG_TRACE_FILE = "LogTrace.txt";

        /// <summary>
        /// 是否启用
        /// </summary>
        private bool IsEnable = false;
        /// <summary>
        /// 轮循秒数
        /// </summary>
        private float LoopSeconds = 3.6f;

        private readonly object StartIdLockObj = new object();

        private long _StartId = 0;
        /// <summary>
        /// 起始流水号
        /// </summary>
        private long StartId
        {
            get
            {
                lock (this.StartIdLockObj)
                {
                    try
                    {
                        if (long.TryParse(Configs.GetAndAdd("StartId", "0"), out var i))
                        {
                            _StartId = i;
                        }
                    }
                    catch (Exception ex)
                    {
                        LogWrite.TxtExport_DateNow(LOG_ERR_FILE, $"DBMan.Deal StartId Get Err:{ex.Message}");
                    }
                    return _StartId;
                }
            }
            set
            {
                lock (this.StartIdLockObj)
                {
                    try
                    {
                        var b = Configs.Write("StartId", value.ToString());
                        if (b)
                        {
                            _StartId = value;
                        }
                    }
                    catch (Exception ex)
                    {
                        LogWrite.TxtExport_DateNow(LOG_ERR_FILE, $"DBMan.Deal StartId Set Err:{ex.Message}");
                    }
                }
            }
        }

        /// <summary>
        /// 数据库类型(0、SQLServer 1、MySQL ...)
        /// </summary>
        private int DBType = 0;

        /// <summary>
        /// 数据库连接字符串
        /// </summary>
        private string DBConnStr = "";
        /// <summary>
        /// 一次获取的数据步长
        /// </summary>
        private int Step = 99;

        private Deal()
        {
            try
            {
                this.IsEnable = (Configs.GetAndAdd("IsEnable", "True").Trim().ToLower() == "true");
                if (!this.IsEnable)
                {
                    return;
                }
                if (float.TryParse(Configs.GetAndAdd("LoopSeconds", "3.5"), out var f))
                {
                    if (f > 0)
                    {
                        this.LoopSeconds = f;
                    }
                }
                object obj = this.StartId;
                if (int.TryParse(Configs.GetAndAdd("DBType", "0"), out var i))
                {
                    this.DBType = i;
                }
                this.DBConnStr = Configs.GetAndAdd("DBConnStr", "server=192.168.0.174;database=TestDB;uid=sa;pwd=123456");

                if (int.TryParse(Configs.GetAndAdd("Step", "100"), out var i2))
                {
                    this.Step = i2;
                }
                this.DealConstructMethod();
                this.DealConstructMethod2();
            }
            catch (Exception ex)
            {
                LogWrite.TxtExport_DateNow(LOG_ERR_FILE, $"DBMan.Deal Err:{ex.Message}");
            }
        }

        public void Start()
        {
            try
            {
                if (!this.IsEnable)
                {
                    LogWrite.TxtExport_DateNow(LOG_TRACE_FILE, $"数据推手数据发送端被设置成禁用!");
                    return;
                }
                this.Init();
                this.DBInit();
                this.GetData();
                LogWrite.TxtExport_DateNow(LOG_TRACE_FILE, $"启用了数据推手数据发送端!");
            }
            catch (Exception ex)
            {
                LogWrite.TxtExport_DateNow(LOG_ERR_FILE, $"DBMan.Deal Start Err:{ex.Message}");
            }
        }

        private void Init()
        {
            try
            {
                var strSQL = "";
                switch (this.DBType)
                {
                    case 0:
                        try
                        {
                            var db = KnDSQLServerHelper.Init(this.DBConnStr);
                            strSQL = $"select max(Id) maxId from TblArchive";
                            var dy = db.QueryToDyList(strSQL).First();
                            var maxId = dy.Get<long?>("maxId");
                            this.StartId = (maxId == null ? 0 : (long)maxId);
                        }
                        catch (Exception ex)
                        {
                            LogWrite.TxtExport_DateNow(LOG_ERR_FILE, $"DBMan.Deal Init 0Err:{ex.Message}");
                        }
                        break;
                    case 1:
                        //...Todo...
                        break;
                }
            }
            catch (Exception ex)
            {
                LogWrite.TxtExport_DateNow(LOG_ERR_FILE, $"DBMan.Deal Init Err:{ex.Message}");
            }
        }
        /// <summary>
        /// 
        /// </summary>
        private void GetData()
        {
            try
            {
                object dbOb = null;
                switch (this.DBType)
                {
                    case 0:
                        dbOb = KnDSQLServerHelper.Init(this.DBConnStr);
                        break;
                    case 1:
                        //...Todo...
                        break;
                }
                var th = new Thread(() =>
                {
                    try
                    {
                        while (true)
                        {
                            Thread.Sleep((int)(this.LoopSeconds * 1000));
                            try
                            {
                                switch (this.DBType)
                                {
                                    case 0:
                                        this.GetData((KnDSQLServerHelper)dbOb);
                                        break;
                                    case 1:
                                        //...Todo...
                                        break;
                                }
                            }
                            catch (Exception ex)
                            {
                                LogWrite.TxtExport_DateNow(LOG_ERR_FILE, $"DBMan.Deal GetData 1Err:{ex.Message}");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LogWrite.TxtExport_DateNow(LOG_ERR_FILE, $"DBMan.Deal GetData 0Err:{ex.Message}");
                    }
                });
                th.Start();
            }
            catch (Exception ex)
            {
                LogWrite.TxtExport_DateNow(LOG_ERR_FILE, $"DBMan.Deal GetData Err:{ex.Message}");
            }
        }
        /// <summary>
        /// 获取SQLServer发送数据
        /// </summary>
        /// <param name="db"></param>
        private void GetData(KnDSQLServerHelper db)
        {
            try
            {
                var strSQL = $"select count(1) cnt from TblArchive ak where ak.Id>{this.StartId}";
                var dt = db.QueryToDyList(strSQL).First();
                var cnt = dt.Get<int>("cnt");
                if (cnt <= 0)
                {
                    return;
                }
                var minId = this.StartId + 1;
                strSQL = $"select max(ak.Id) maxId from TblArchive ak where ak.Id>={minId}";
                dt = db.QueryToDyList(strSQL).First();
                var maxId = dt.Get<long>("maxId");
                var iStep = this.Step;
                var iStart = minId;
                while (true)
                {
                    var iEnd = iStart + iStep;
                    if ((iStart == minId) && (cnt <= iStep))
                    {
                        iEnd = maxId;
                    }
                    if (iEnd >= maxId)
                    {
                        iEnd = maxId;
                        if (iStart > iEnd)
                        {
                            iStart = iEnd;
                        }
                        this.DataPushDeal(db, iStart, iEnd);
                        break;
                    }
                    if (iStart > iEnd)
                    {
                        iStart = iEnd;
                    }
                    this.DataPushDeal(db, iStart, iEnd);
                    iStart = iEnd + 1;
                }
                this.StartId = maxId;
                strSQL = $"delete from TblArchive where Id<={(minId - 1)}";
                db.Execute(strSQL);
            }
            catch (Exception ex)
            {
                LogWrite.TxtExport_DateNow(LOG_ERR_FILE, $"DBMan.Deal GetData 0 Err:{ex.Message}");
            }
        }

        private void DataPushDeal(KnDSQLServerHelper db, long iStart, long iEnd)
        {
            try
            {
                var strSQL = $"select count(1) cnt from TblArchive ak where ak.Id between {iStart} and {iEnd}";
                var dt = db.QueryToDyList(strSQL).First();
                var cnt = dt.Get<int>("cnt");
                if (cnt <= 0)
                {
                    return;
                }
                strSQL = $"select * from TblArchive ak where ak.Id between {iStart} and {iEnd} order by ak.Id";
                var json = db.QueryToJson(strSQL);
                var th = new Thread((ob) =>
                {
                    try
                    {
                        var _json = (string)ob;
                        //把获得的摘要数据推送出去
                        this.UdpPublish(_json);
                        this.MqttPublish(_json);
                    }
                    catch (Exception ex)
                    {
                        LogWrite.TxtExport_DateNow(LOG_ERR_FILE, $"DBMan.Deal DataPushDeal 0Err:{ex.Message}");
                    }
                });
                th.Start(json);
            }
            catch (Exception ex)
            {
                LogWrite.TxtExport_DateNow(LOG_ERR_FILE, $"DBMan.Deal DataPushDeal Err:{ex.Message}");
            }
        }

    }
}